Component Objects: C++ Nested Classes
The next
example shows how the same object is declared and initialized using the C++
nested class approach. As in the C example, the nested class declaration
includes one data structure for each interface and four private data members:
an object-level reference count, two interface pointers, and a pointer to the
enclosing object. The private implementations of the IUnknown
The benefits
of implementing with C++ nested classes lie in the ability to include
initialization code and method implementation inline. However, inline
declaration is for the convenience of illustration and is not required.
class
CObj {
private:
ULONG m_ObjRefCount;
LPSTORAGE m_pStg;
LPOLEOBJECT m_pOleObj;
CDOC *
m_pCDoc;
public:
CObj();
~CObj();
struct
CUnknown : IUnknown
{
private:
ULONG m_RefCount;
CObj *
m_pCObj;
public:
CUnknown(CObj (pCObj)
{ m_pCObj =
pCObj; m_RefCount = 0; }
HRESULT
QueryInterface(REFIID riid, LPVOID *
ppvObj)
ULONG
AddRef(void) { return ++m_ObjRefCount; }
ULONG
Release(void);
}
friend CUnknown;
CUnknown m_Unknown;
struct InterfaceA : InterfaceA
{
private:
ULONG m_RefCount;
CObj *
m_pCObj;
public:
CInterfaceA(CObj
*pCObj)
{ m_pCObj =
pCObj; m_RefCount = 0; }
HRESULT
QueryInterface(REFIID riid, LPVOID *
ppvObj)
ULONG
AddRef(void) { return ++m_ObjRefCount; }
ULONG
Release(void);
HRESULT
MethodA1(LPVOID * ppvObj);
HRESULT
MethodA2(DWORD dwArg);
}
friend CInterfaceA;
CInterfaceA m_InterfaceA;
struct InterfaceB : InterfaceB
{
private:
ULONG m_RefCount;
CObj *
m_pCObj;
public:
CInterfaceB(CObj *pCObj)
{ m_pCObj =
pCObj; m_RefCount = 0; }
HRESULT
QueryInterface(REFIID riid, LPVOID *
ppvObj)
ULONG AddRef(void)
{ return ++m_ObjRefCount; }
ULONG
Release(void);
HRESULT
MethodB1(void);
HRESULT
MethodB2(DWORD dwArg1, DWORD dwArg2);
}
friend CInterfaceB;
CInterfaceB m_InterfaceB;